package com.googlecode.archimedes.filegen.generator.velocity;

/**
 * General utility class to handle utility functions needed inside of a Velocity .vm file.
 * 
 * @author John Lema, Erik Gustavson
 *
 */
import java.io.File;
import java.net.URL;
import java.util.StringTokenizer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class VelocityUtil {
	private Log logger = LogFactory.getLog(this.getClass().getName());

	/**
	 *  The search path for non-classpath searches
	 */
	public String path;

	/**
	 * Handles searching for file existance by looking through either the
	 * classpath or the comma-seperated values of the path element.
	 * 
	 * @param name The name of the file to be found
	 * @return a boolean if the file exists
	 */
	public boolean fileExists(String name) {
		try {
			if (searchClassPath(name)) {
				logger.debug("Found it by classpath.");
				return true;
			}

			if (searchPaths(path, name)) {
				logger.debug("Found it by paths.");
				return true;
			}
		} catch (Exception e) {
			logger.error("There was a problem looking for the file", e);
		}

		return false;
	}

	/**
	 * Searches the classpath
	 * 
	 * @param name the Name of the file to be found
	 * @return a boolean if the file is found
	 */
	private boolean searchClassPath(String name) {
		ClassLoader loader = this.getClass().getClassLoader();
		URL url = loader.getResource(path + name);
		if (url != null) {
			logger.info("Found url [" + url + "] for name [" + name + "]");
			return true;
		}
		return false;
	}

	/**
	 * Handler for searching paths
	 * 
	 * @param paths a comma seperated list of paths
	 * @param name the name of the file to be found
	 * @return a boolean if the file is found
	 */
	private boolean searchPaths(String paths, String name) {

		StringTokenizer tokenizer = new StringTokenizer(paths, ",");
		while (tokenizer.hasMoreTokens()) {
			String token = tokenizer.nextToken();
			logger.info("Searching path:" + token);
			if (searchPath(token.trim(), name)) {
				return true;
			}

		}

		return false;
	}

	/**
	 * recusively searches an individual path
	 * 
	 * @param path The path to search
	 * @param name the name of the file to be found
	 * @return a boolean if the file is found
	 */
	private boolean searchPath(String path, String name) {
		logger.debug("Searching path [" + path + "] for file [" + name + "]");
		File file = new File(path);
		if (file.exists()) {
			if (file.isDirectory()) {
				File[] files = file.listFiles();
				for (int i = 0; i < files.length; i++) {
					if (searchPath(files[i].getAbsolutePath(), name)) {
						return true;
					}
				}
			} else {
				if (file.getName().equalsIgnoreCase(name)) {
					return true;
				}
			}
		}

		return false;
	}

}
